//
//  FMRichTextView.m
//  TestDemo
//
//  Created by fengxijun on 4/21/16.
//  Copyright © 2016 goappbox. All rights reserved.
//

#import "FMRichTextView.h"
#import <CoreText/CoreText.h>

@implementation FMRichTextView

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        [self setUp];
    }
    return self;
}

- (instancetype)initWithCoder:(NSCoder *)aDecoder
{
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self setUp];
    }
    return self;
}

- (void)setUp
{
    self.font = [UIFont systemFontOfSize:15.f];
}

//- (CGSize)sizeThatFits:(CGSize)size
//{
//    NSMutableAttributedString *attrStr = [self mutableAttributedString];
//    if (attrStr == nil) {
//        return CGSizeZero;
//    }
//    
//    return [self contentSizeWithAttrString:attrStr size:size];
//}
//
//- (CGSize)contentSizeWithAttrString:(NSMutableAttributedString *)attrString size:(CGSize)size
//{
////    [attrString enumerateAttributesInRange:NSMakeRange(0, [attrString length]) options:NSAttributedStringEnumerationReverse usingBlock:^(NSDictionary<NSString *,id> * _Nonnull attrs, NSRange range, BOOL * _Nonnull stop) {
////        NSLog(@"%@ ::: %@",attrs, NSStringFromRange(range));
////    }];
//    return [self boundingRectWithSize:size attString:attrString].size;
//}
//
//- (void)setAttributedText:(NSAttributedString *)attributedText
//{
//    _attributedText = attributedText;
//}
//
//- (void)setText:(NSString *)text
//{
//    _text = [text copy];
//}
//
//- (NSMutableAttributedString *)mutableAttributedString
//{
//    NSMutableAttributedString *attrString = [[NSMutableAttributedString alloc] init];
//    if (self.text != nil) {
//        self.attributedText = [[NSAttributedString alloc] initWithString:self.text];
//        
//    }
//    
//    if (self.attributedText == nil) {
//        return nil;
//    }
//    
//    attrString = [[NSMutableAttributedString alloc] initWithAttributedString:self.attributedText];
//    
////    CTFontRef fontRef = CTFontCreateWithName((__bridge CFStringRef)self.font.fontName, self.font.pointSize, NULL);
////    
////    [attrString addAttribute:(NSString *)kCTFontAttributeName value:(__bridge id)fontRef range:NSMakeRange(0, attrString.length)];
//    
//    [attrString addAttribute:NSFontAttributeName value:self.font range:NSMakeRange(0, attrString.length)];
//    
//    //换行模式
//    CTParagraphStyleSetting lineBreakModel;
//    CTLineBreakMode lineBreak = (CTLineBreakMode) self.lineBreakMode;
//    lineBreakModel.spec = kCTParagraphStyleSpecifierLineBreakMode;
//    lineBreakModel.value = &lineBreak;
//    lineBreakModel.valueSize = sizeof(lineBreak);
//    
//    CTParagraphStyleSetting lineSpaceStyle;
//    lineSpaceStyle.spec = kCTParagraphStyleSpecifierLineSpacing;
//    lineSpaceStyle.valueSize = sizeof(self.lineSpace);
//    CGFloat lineSpace = self.lineSpace;
//    lineSpaceStyle.value = &lineSpace;
//    
//    CTParagraphStyleSetting settings[] = {lineBreakModel,lineSpaceStyle};
//    CTParagraphStyleRef style = CTParagraphStyleCreate(settings, sizeof(settings) / sizeof(settings[0]));
//    NSMutableDictionary *attributes = [NSMutableDictionary dictionaryWithObject:(__bridge id)style forKey:(__bridge id)kCTParagraphStyleAttributeName];
//    CFRelease(style);
//    
//    [attrString addAttributes:attributes range:NSMakeRange(0, [attrString length])];
////    [attrString addAttribute:(__bridge id)kCTForegroundColorAttributeName value:[UIColor yellowColor] range:NSMakeRange(0, 5)];
////    [attrString addAttribute:@"IMG" value:@"IMG_TAG" range:NSMakeRange(5, 5)];
//    return attrString;
//}
//
//- (void)sizeToFit
//{
//    self.contentSize = [self sizeThatFits:CGSizeMake(self.frame.size.width, MAXFLOAT)];
//    [self setNeedsDisplay];
//}
//
//- (void)layoutSubviews
//{
//    [super layoutSubviews];
//    [self sizeToFit];
//}
//
//- (void)drawRect:(CGRect)rect
//{
//    NSMutableAttributedString *attrStr = [self mutableAttributedString];
//    if (attrStr == nil) {
//        return;
//    }
//    
//    CGContextRef contextRef = UIGraphicsGetCurrentContext();
//    
//    CGAffineTransform affineTransform = CGAffineTransformIdentity;
//    affineTransform = CGAffineTransformMakeTranslation(0.0, self.frame.size.height);
//    affineTransform = CGAffineTransformScale(affineTransform, 1.0, -1.0);
//    CGContextConcatCTM(contextRef, affineTransform);
//    
//    CGMutablePathRef pathRef = CGPathCreateMutable();
//    CGPathAddRect(pathRef, NULL, self.bounds);
//    
//    //创建一个framesetter用来管理描画文字的frame  CTFramesetter
//    CTFramesetterRef framesetterRef = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attrStr);
//    
//    //创建由framesetter管理的frame，是描画文字的一个视图范围  CTFrame
//    CTFrameRef frameRef = CTFramesetterCreateFrame(framesetterRef, CFRangeMake(0, 0), pathRef, nil);
//    
//    CFArrayRef lines = CTFrameGetLines(frameRef);
//    
//    CGPoint lineOrigins[CFArrayGetCount(lines)];
//    CTFrameGetLineOrigins(frameRef, CFRangeMake(0, 0), lineOrigins);
//    
//    for (int i = 0; i < CFArrayGetCount(lines); i++)
//    {
//        CTLineRef lineRef= CFArrayGetValueAtIndex(lines, i);
//        CGFloat lineAscent;
//        CGFloat lineDescent;
//        CGFloat lineLeading;
//        CGPoint lineOrigin = lineOrigins[i];
//        CTLineGetTypographicBounds(lineRef, &lineAscent, &lineDescent, &lineLeading);
//        CFArrayRef runs = CTLineGetGlyphRuns(lineRef);
//        
//        for (int j = 0; j < CFArrayGetCount(runs); j++)
//        {
//            CTRunRef runRef = CFArrayGetValueAtIndex(runs, j);
//            CGFloat runAscent;
//            CGFloat runDescent;
//            CGRect runRect;
//            
//            runRect.size.width = CTRunGetTypographicBounds(runRef, CFRangeMake(0,0), &runAscent, &runDescent, NULL);
//            runRect = CGRectMake(lineOrigin.x + CTLineGetOffsetForStringIndex(lineRef, CTRunGetStringRange(runRef).location, NULL),
//                                 lineOrigin.y ,
//                                 runRect.size.width,
//                                 runAscent + runDescent);
//            
////            NSDictionary * attributes = (__bridge NSDictionary *)CTRunGetAttributes(runRef);
////            TQRichTextRun *richTextRun = [attributes objectForKey:kTQRichTextRunSelfAttributedName];
//            
////            if (richTextRun.drawSelf)
////            {
////                CGFloat runAscent,runDescent;
////                CGFloat runWidth  = CTRunGetTypographicBounds(runRef, CFRangeMake(0,0), &runAscent, &runDescent, NULL);
////                CGFloat runHeight = (lineAscent + lineDescent );
////                CGFloat runPointX = runRect.origin.x + lineOrigin.x;
////                CGFloat runPointY = lineOrigin.y ;
////                
////                CGRect runRectDraw = CGRectMake(runPointX, runPointY, runWidth, runHeight);
////                
////                [richTextRun drawRunWithRect:runRectDraw];
////                
////                [self.runRectDictionary setObject:richTextRun forKey:[NSValue valueWithCGRect:runRectDraw]];
////            }
////            else
////            {
////                if (richTextRun)
////                {
////                    [self.runRectDictionary setObject:richTextRun forKey:[NSValue valueWithCGRect:runRect]];
////                }
////            }
//        }
//    }
//    
//    //通过context在frame中描画文字内容
//    CTFrameDraw(frameRef, contextRef);
//    
//    CFRelease(pathRef);
//    CFRelease(frameRef);
//    CFRelease(framesetterRef);
//}
//
//- (CGRect)boundingRectWithSize:(CGSize)size attString:(NSMutableAttributedString *)attString
//{
//    NSDictionary *dic = [attString attributesAtIndex:0 effectiveRange:nil];
//    CTParagraphStyleRef paragraphStyle = (__bridge CTParagraphStyleRef)[dic objectForKey:(id)kCTParagraphStyleAttributeName];
//    CGFloat linespace = 0;
//    
//    CTParagraphStyleGetValueForSpecifier(paragraphStyle, kCTParagraphStyleSpecifierLineSpacing, sizeof(linespace), &linespace);
//    
//    CGFloat height = 0;
//    CGFloat width = 0;
//    CFIndex lineIndex = 0;
//    
//    CGMutablePathRef pathRef = CGPathCreateMutable();
//    CGPathAddRect(pathRef, NULL, CGRectMake(0, 0, size.width, size.height));
//    CTFramesetterRef framesetterRef = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)attString);
//    CTFrameRef frameRef = CTFramesetterCreateFrame(framesetterRef, CFRangeMake(0, 0), pathRef, nil);
//    CFArrayRef lines = CTFrameGetLines(frameRef);
//    
//    lineIndex = CFArrayGetCount(lines);
//    
//    if (lineIndex > 1)
//    {
//        for (int i = 0; i <lineIndex ; i++)
//        {
//            CTLineRef lineRef= CFArrayGetValueAtIndex(lines, i);
//            CGFloat lineAscent;
//            CGFloat lineDescent;
//            CGFloat lineLeading;
//            CTLineGetTypographicBounds(lineRef, &lineAscent, &lineDescent, &lineLeading);
//            
//            if (i == lineIndex - 1)
//            {
//                height += (lineAscent + lineDescent );
//            }
//            else
//            {
//                height += (lineAscent + lineDescent + linespace);
//            }
//        }
//        
//        width = size.width;
//    }
//    else
//    {
//        for (int i = 0; i <lineIndex ; i++)
//        {
//            CTLineRef lineRef= CFArrayGetValueAtIndex(lines, i);
//            CGRect rect = CTLineGetBoundsWithOptions(lineRef,kCTLineBoundsExcludeTypographicShifts);
//            width = rect.size.width;
//            
//            CGFloat lineAscent;
//            CGFloat lineDescent;
//            CGFloat lineLeading;
//            CTLineGetTypographicBounds(lineRef, &lineAscent, &lineDescent, &lineLeading);
//            
//            height += (lineAscent + lineDescent + lineLeading + linespace);
//        }
//        
//        height = height;
//    }
//    
//    CFRelease(pathRef);
//    CFRelease(frameRef);
//    CFRelease(framesetterRef);
//    
//    CGRect rect = CGRectMake(0,0,width,height);
//    
//    return rect;
//}

//-(NSDictionary*)textAttributesAtPoint:(CGPoint)pt
//{
//    // Locate the attributes of the text within the label at the specified point
//    NSDictionary* dictionary = nil;
//    
//    // First, create a CoreText framesetter
//    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((__bridge CFAttributedStringRef)self.attributedText);
//    
//    CGMutablePathRef framePath = CGPathCreateMutable();
//    CGPathAddRect(framePath, NULL, CGRectMake(0, 0, self.frame.size.width, self.frame.size.height));
//    // Get the frame that will do the rendering.
//    CFRange currentRange = CFRangeMake(0, 0);
//    CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, currentRange, framePath, NULL);
//    CGPathRelease(framePath);
//    
//    // Get each of the typeset lines
//    NSArray *lines = (__bridge id)CTFrameGetLines(frameRef);
//    
//    CFIndex linesCount = [lines count];
//    CGPoint *lineOrigins = (CGPoint *) malloc(sizeof(CGPoint) * linesCount);
//    CTFrameGetLineOrigins(frameRef, CFRangeMake(0, linesCount), lineOrigins);
//    
//    CTLineRef line = NULL;
//    CGPoint lineOrigin = CGPointZero;
//    
//    // Correct each of the typeset lines (which have origin (0,0)) to the correct orientation (typesetting offsets from the bottom of the frame)
//    
//    CGFloat bottom = self.frame.size.height;
//    for(CFIndex i = 0; i < linesCount; ++i) {
//        lineOrigins[i].y = self.frame.size.height - lineOrigins[i].y;
//        bottom = lineOrigins[i].y;
//    }
//    
//    // Offset the touch point by the amount of space between the top of the label frame and the text
//    pt.y -= (self.frame.size.height - bottom)/2;
//    
//    
//    // Scan through each line to find the line containing the touch point y position
//    for(CFIndex i = 0; i < linesCount; ++i) {
//        line = (__bridge CTLineRef)[lines objectAtIndex:i];
//        lineOrigin = lineOrigins[i];
//        CGFloat descent, ascent;
//        CGFloat width = CTLineGetTypographicBounds(line, &ascent, &descent, nil);
//        
//        if(pt.y < (floor(lineOrigin.y) + floor(descent))) {
//            
//            // Cater for text alignment set in the label itself (not in the attributed string)
//            if (self.textAlignment == NSTextAlignmentCenter) {
//                pt.x -= (self.frame.size.width - width)/2;
//            } else if (self.textAlignment == NSTextAlignmentRight) {
//                pt.x -= (self.frame.size.width - width);
//            }
//            
//            // Offset the touch position by the actual typeset line origin. pt is now the correct touch position with the line bounds
//            pt.x -= lineOrigin.x;
//            pt.y -= lineOrigin.y;
//            
//            // Find the text index within this line for the touch position
//            CFIndex i = CTLineGetStringIndexForPosition(line, pt);
//            
//            // Iterate through each of the glyph runs to find the run containing the character index
//            NSArray* glyphRuns = (__bridge id)CTLineGetGlyphRuns(line);
//            CFIndex runCount = [glyphRuns count];
//            for (CFIndex run=0; run<runCount; run++) {
//                CTRunRef glyphRun = (__bridge CTRunRef)[glyphRuns objectAtIndex:run];
//                CFRange range = CTRunGetStringRange(glyphRun);
//                if (i >= range.location && i<= range.location+range.length) {
//                    dictionary = (__bridge NSDictionary*)CTRunGetAttributes(glyphRun);
//                    break;
//                }
//            }
//            if (dictionary) {
//                break;
//            }
//        }
//    }
//    
//    free(lineOrigins);
//    CFRelease(frameRef);
//    CFRelease(framesetter);
//    
//    
//    return dictionary;
//}

@end
